<template>
  <!-- 头部搜索组件 -->
  <el-form class="query-container" ref="queryFormRef" :model="queryParams" :inline="true" @submit.native.prevent>
    <el-form-item label="标题" prop="username">
      <el-input
          v-model="queryParams.title"
          placeholder="请输入标题"
          clearable
          @keyup.enter.native="handleQuery"
      />
    </el-form-item>
    <el-form-item label="类别" prop="categoryId">
      <el-select
          v-model="queryParams.categoryId"
          placeholder="请选择类别"
          style="width: 150px"
      >
        <el-option
            v-for="item in categoryOptions"
            :key="item.id"
            :label="item.categoryName"
            :value="item.id"
        />
      </el-select>
    </el-form-item>
    <el-form-item label="发布状态" prop="status">
      <el-select
          v-model="queryParams.status"
          placeholder="请选择状态"
          style="width: 150px"
      >
        <el-option
            v-for="item in statusOptions"
            :key="item.id"
            :label="item.statusName"
            :value="item.id"
        />
      </el-select>
    </el-form-item>
    <el-form-item>
      <el-button type="primary" @click="handleQuery">搜索</el-button>
      <el-button @click="resetQuery">重置</el-button>
    </el-form-item>
  </el-form>

  <div class="inner-container">
    <!--  资讯增删改  -->
    <el-row :gutter="10" style="margin-bottom:8px">
      <el-col :span="1.5">
        <el-button type="primary" plain @click="showAddDialog">新增</el-button>
      </el-col>
      <el-col :span="1.5">
        <el-button type="success" plain @click="showEditDialog" :disabled="selectedIds.length!==1">修改</el-button>
      </el-col>
      <el-col :span="1.5">
        <el-button type="danger" plain @click="handleDelete(null)" :disabled="!selectedIds.length">删除</el-button>
      </el-col>
    </el-row>

    <!--  资讯列表展示  -->
    <el-table v-loading="loading" :data="tableData" @selection-change="handleSelectionChange">
      <el-table-column type="selection" width="50"/>
      <el-table-column prop="category" label="类别" align="center" :formatter="formatCategory"/>
      <el-table-column prop="imgUrl" label="封面" align="center">
        <template #default="scope">
          <div><img :src="scope.row.imgUrl" style="width: 75px;height: 55px;" alt=""></div>
        </template>
      </el-table-column>
      <el-table-column prop="title" label="标题" show-overflow-tooltip align="center"/>
      <el-table-column prop="brief" label="简介" show-overflow-tooltip align="center"/>
      <el-table-column prop="createdTime" label="创建时间" show-overflow-tooltip align="center"/>
      <el-table-column prop="createdBy" label="创建人" show-overflow-tooltip align="center"/>
      <el-table-column prop="sendTime" label="发布时间" show-overflow-tooltip align="center"/>
      <el-table-column prop="status" label="状态" align="center">
        <template #default="scope">
          <span v-if="scope.row.status===1" style="color:darkorange; font-size: 12px;">待发布</span>
          <span v-else style="color: green;font-size: 12px; ">已发布</span>
        </template>
      </el-table-column>
      <el-table-column label="操作" fixed="right" width="180" align="center">
        <template #default="scope">
          <el-button type="primary" link icon="Position" :disabled="scope.row.status===2" @click="sendNews(scope.row)">
            发布
          </el-button>
          <el-button type="primary" link icon="Edit" @click="showEditDialog(scope.row)">修改</el-button>
          <el-button type="danger" link icon="Delete" @click="handleDelete(scope.row)">删除</el-button>
        </template>
      </el-table-column>
    </el-table>

    <br>
    <!--  分页展示  -->
    <el-pagination
        :total="total"
        v-model:current-page="queryParams.pageNum"
        v-model:page-size="queryParams.pageSize"
        @size-change="handleSizeChange"
        @current-change="handleCurrentChange"/>

    <!--  资讯增加、修改  -->
    <el-dialog v-model="dialogVisible" :title="dialogTitle" :before-close="closeDialog" append-to-body
               :close-on-click-modal="false" style="width:80%;padding-right: 50px;">
      <el-form ref="dialogFormRef" :model="formData" label-width="100px">
        <el-form-item label="资讯标题" prop="title">
          <el-input placeholder="请输入资讯标题" v-model="formData.title"/>
        </el-form-item>
        <el-form-item label="资讯简介" prop="brief">
          <el-input placeholder="请输入资讯简介" v-model="formData.brief"/>
        </el-form-item>
        <el-form-item label="资讯分类" prop="category">
          <!-- 下拉选框设置双向绑定与文本占位符 -->
          <el-select v-model="formData.categoryId" placeholder="请选择分类">
            <el-option v-for="item in categoryOptions" :label="item.categoryName" :value="item.id"></el-option>
          </el-select>
        </el-form-item>
        <!--封面上传开始-->
        <el-form-item label="资讯封面" prop="imgUrl">
          <el-upload action=""
                     list-type="picture-card"
                     v-model:file-list="thumbnailTempList"
                     :http-request="uploadFileThumbnail"
                     :limit="1"
          >
            <!-- 默认上传图标，使用Element Plus的Plus图标 -->
            <el-icon>
              <Plus/>
            </el-icon>
            <!-- 自定义文件列表模板 -->
            <template #file="{ file }">
              <div>
                <!-- 显示文件的缩略图 -->
                <img class="el-upload-list__item-thumbnail" :src="file.url" alt=""/>
                <!-- 文件操作按钮容器 -->
                <span class="el-upload-list__item-actions">
                  <!-- 预览图片按钮 -->
                  <span
                      class="el-upload-list__item-preview"
                      @click="handlePictureCardPreview(file)">
                    <el-icon><zoom-in/></el-icon>
                  </span>
                  <!-- 删除文件按钮，仅在未禁用时显示 -->
                  <span
                      v-if="!disabled"
                      class="el-upload-list__item-delete"
                      @click="handleRemove(file)">
                    <el-icon><Delete/></el-icon>
                  </span>
                </span>
              </div>
            </template>
          </el-upload>

          <el-dialog v-model="dialogImageVisible" style="z-index: 999;width: 70%; padding: 50px;">
            <img :src="dialogImageUrl" alt="Preview Image" style="width: 100%;"/>
          </el-dialog>
        </el-form-item>
        <!--封面上传结束-->
        <el-form-item label="资讯内容" prop="content">
          <div ref="editorDiv" style="width: 100%;z-index: 11"></div>
        </el-form-item>
      </el-form>
      <template #footer class="dialog-footer">
        <el-button type="primary" @click="saveOrUpdate">保存</el-button>
        <el-button @click="closeDialog">取消</el-button>
      </template>
    </el-dialog>
  </div>
</template>

<script setup>
import {nextTick, onMounted, ref} from 'vue'
import {ElMessage, ElMessageBox,} from 'element-plus'
import request from '@/utils/request'
import Editor from "wangeditor";

// --------------------------------------------------
const loading = ref(false)
const queryFormRef = ref()
const queryParams = ref({pageNum: 1, pageSize: 10})
const total = ref(0)
const tableData = ref([])
const selectedIds = ref([])

// 表单规则
const formRules = ref({
  title: [{required: true, message: '资讯标题为必填项'}],
  brief: [{required: true, message: '资讯简介为必填项'}],
  categoryId: [{required: true, message: '资讯分类为必填项'}],
  imgUrl: [{required: true, message: '资讯封面为必填项'}],
  content: [{required: true, message: '资讯内容为必填项'}]
})


//保存资讯类别下拉列表
const categoryOptions = ref();
//保存资讯状态下拉列表
const statusOptions = ref();

// 资讯列表查询请求
const listData = () => {
  loading.value = true; // 设置 loading 状态为 true，表示数据正在加载中
  // 发起 HTTP GET 请求到 '/api/bus/news' 接口，使用 queryParams.value 作为查询参数
  request.get('/api/bus/news', {
    params: queryParams.value  // queryParams.value 可能是一个存储查询参数的变量或响应式对象
  }).then(res => {
    // 请求成功后的回调函数
    total.value = res.data.total; // 将返回数据中的 total 字段赋值给 total.value
    tableData.value = res.data.list; // 将返回数据中的 list 字段赋值给 tableData.value
    loading.value = false; // 数据加载完成，设置 loading 状态为 false
  });
};

// 资讯类别查询请求
const categoryData = () => {
  loading.value = true;
  request.get('/api/bus/news/category').then(res => {
    categoryOptions.value = res.data;
    loading.value = false;
  })
}

// 资讯状态查询
const statusData = () => {
  loading.value = true;
  request.get('/api/bus/news/status').then(res => {
    statusOptions.value = res.data;
    loading.value = false;
  })
}

// 类别转换显示
const formatCategory = (row) => {
  for (let i = 0; i < categoryOptions.value.length; i++) {
    if (row.categoryId === categoryOptions.value[i].id) {
      return categoryOptions.value[i].categoryName
    }
  }
}


//--------------资讯新增页相关 start--------------------
//创建响应式变量，代表页面的div元素
const editorDiv = ref(null);
//用来保存富文本编辑器对象
let editor = null;
//挂在完毕执行的方法
const loadEditor = () => {
  editor = new Editor(editorDiv.value);
  editor.config.placeholder = "请输入内容...";
  editor.create()
  //把获取到的当前文章内容回显到富文本编辑器中
  editor.txt.html(formData.value.content)
}


const dialogTitle = ref('')
const dialogVisible = ref(false)
const dialogFormRef = ref()
const formData = ref({
  id: undefined,
  title: undefined,
  brief: undefined,
  categoryId: undefined,
  imgUrl: [],
  content: undefined
})

//新增资讯弹窗显示
const showAddDialog = () => {
  dialogTitle.value = '资讯新增';
  dialogVisible.value = true;
  //nextTick 是一个在 JavaScript 中常见的概念，特别是在处理异步操作时比较常用。
  //它通常用于在当前调用栈执行完毕后（当前事件循环结束时），执行一个回调函数或者代码片段，这样可以确保该回调函数是在所有同步操作执行完毕后执行的。
  //这种方式适合需要在当前代码执行周期结束后立即执行的任务，例如确保在浏览器渲染或其他异步操作完成之后立即执行一些代码。
  nextTick(() => {
    loadEditor();
  })

};

//修改资讯弹窗显示
const showEditDialog = (row) => {
  let id = row.id || selectedIds.value
  request.get(`/api/bus/news/${id}`)
      .then(res => {
        formData.value = res.data
        dialogTitle.value = '修改资讯'
        dialogVisible.value = true;
        dialogImageUrl.value=res.data.imgUrl;
        thumbnailTempList.value = [{url: res.data.imgUrl}]
        nextTick(() => {
          loadEditor();
        })
      })
}


//资讯弹窗关闭操作
const closeDialog = () => {
  //关闭之前清空表单数据
  formData.value = {
    id: undefined,
    title: undefined,
    brief: undefined,
    categoryId: undefined,
    imgUrl: [],
    content: undefined
  };
  editor.destroy();
  //重置表单字段的状态。
  dialogFormRef.value.resetFields()
  dialogVisible.value = false

  //重置上传图片缩略图列表
  thumbnailTempList.value = [];
}

//保存创建的资讯
const saveOrUpdate = () => {
  dialogFormRef.value.validate(valid => {
    if (!valid) {
      ElMessage.error('请正确填写参数')
      return
    }
    //保存富文本的内容
    formData.value.content = editor.txt.html();

    //发送请求
    request({
      url: '/api/bus/news/saveCreate',
      method: 'post',
      data: formData.value
    }).then(res => {
      //关闭弹窗
      closeDialog()
      //重新加载
      listData()
      ElMessage.success('保存成功')
    });
  })
}


//保存图片--------------------

// 导入Element Plus图标组件
import {Delete, Plus, ZoomIn} from '@element-plus/icons-vue';

// 定义一个响应式的数组，用于存储上传文件的列表
let thumbnailTempList = ref([]);
// 定义用于预览图片的URL的响应式引用
const dialogImageUrl = ref('');
// 定义用于控制预览对话框可见性的响应式引用
const dialogImageVisible = ref(false);
// 定义是否禁用删除和下载操作的响应式引用
const disabled = ref(false);

/**
 * 上传文件的处理函数
 * @param {Object} file - 包含上传文件信息的对象
 * 返回图片生成地址
 */
function uploadFileThumbnail(file){
  const formImgData = new FormData()
  formImgData.append('file',file.file)
  request({
    url: '/file/upload',
    method:'post',
    data: formImgData
  }).then(res => {
    file.onSuccess(res.data)
    dialogImageUrl.value=res.data;
    formData.value.imgUrl = res.data;
  })
}

// 预览图片的处理函数
const handlePictureCardPreview = (file) => {
  // 设置预览图片的URL
  dialogImageUrl.value = file.url;
  // 显示预览对话框
  dialogImageVisible.value = true;
};

// 删除文件的处理函数
const handleRemove = (file) => {
  dialogImageUrl.value = '';// 清空当前预览图片
  thumbnailTempList.value = []; // 清空上传列表，如果列表只用于显示预览的话
  formData.value.imgUrl = []; //清空当前表单图片数据
};




//--------------资讯新增页相关 end--------------------

//修改弹窗
const handleSelectionChange = (selection) => {
  selectedIds.value = selection.map(item => item.id)
}

//搜索资讯列表
const handleQuery = () => {
  queryParams.value.pageNum = 1
  listData();
}
//重置查询条件
const resetQuery = () => {
  queryFormRef.value.resetFields()
  handleQuery()
}

//分页改变
const handleCurrentChange = (val) => {
  queryParams.value.pageNum = val
  listData()
}

//分页按钮改变
const handleSizeChange = (val) => {
  queryParams.value.pageSize = val
  listData()
}


//资讯发布请求
const sendNews = (row) => {
  let id = row.id;
  ElMessageBox.confirm('确定发布吗？', '提示', {
    type: "info"
  }).then(() => {
    request.post(`/api/bus/news/send?id=${id}`)
        .then(res => {
          listData()
          ElMessage.success('发布成功')
        })
  }).catch(() => {
  })
}


//资讯删除请求
const handleDelete = (row) => {
  let ids = row ? [row.id] : [...selectedIds.value]
  if (ids.length === 0) {
    ElMessage.error('请选择要删除的记录')
    return
  }
  ElMessageBox.confirm('确定删除吗？', '提示', {
    type: 'warning'
  }).then(() => {
    request.delete(`/api/bus/news/del?ids=${ids}`)
        .then(res => {
          selectedIds.value.length = 0
          listData()
          ElMessage.success('删除成功')
        })
  }).catch(() => {
  })
}


// --------------------------------------------------
onMounted(() => {
  categoryData();
  statusData();
  nextTick(() => {
    listData()
  })

})


</script>

<style scoped>

</style>
